package biolabs.mcl

import biolabs.core.{Application, Interaction}
import biolabs.mcl.syntax._

import java.lang.reflect.Method

object ExplicitParticipation {
	def analyze(ast: ParticipationAST, model: ModelDefinition, app: Application): AnalysisResult[ExplicitParticipation] = {
		// analyze the interaction type
		val iaType = SingleType.analyze(ast.action, model, model.typeParameterMap, app) match {
			case AnalysisSuccess(t) => t match {
				case u: ActualType => u
				case v: TypeVar => return AnalysisError("Cannot use type variable " + v.name + " as an action type.")
			}
			case AnalysisError(msg) => return AnalysisError(msg)
		}

		// check that the interaction type extends Interaction
		if(!classOf[Interaction[_, _, _, _, _]].isAssignableFrom(iaType.rawType))
			return AnalysisError(iaType.rawType + " which does not extend " + classOf[Interaction[_, _, _, _, _]] + " used as interaction")

		// analyze delegate combination
		val delegateCombination = DelegateCombination.analyze(ast.delegateCombination, model, iaType, app) match {
			case AnalysisSuccess(dc) => dc
			case AnalysisError(msg) => return AnalysisError(msg)
		}

		AnalysisSuccess(new ExplicitParticipation(iaType, delegateCombination))
	}
}

/** Represents an explicit definition of how a model participates
  * in a particular interaction, that is, how a delegate for that
  * interaction is formed.
  */
class ExplicitParticipation(
		val interaction: ActualType,
		val delegateCombination: DelegateCombination)